package edu.neu.ecommerceplatform.service.Impl;

import edu.neu.ecommerceplatform.Exception.ResourceNotFoundException;
import edu.neu.ecommerceplatform.dto.CreateDeliverRequest;
import edu.neu.ecommerceplatform.dto.DeliverInfoResponse;
import edu.neu.ecommerceplatform.dto.UpdateDeliverRequest;
import edu.neu.ecommerceplatform.mapper.*;
import edu.neu.ecommerceplatform.model.*;
import edu.neu.ecommerceplatform.service.DeliverService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class DeliverServiceImpl implements DeliverService {

    private static final Logger logger = LoggerFactory.getLogger(DeliverServiceImpl.class);

    private final DeliverMapper deliverMapper;
    private final OrderMapper orderMapper;
    private final UserMapper userMapper;
    private final AddressMapper addressMapper;
    private final ProductMapper productMapper;

    @Autowired
    public DeliverServiceImpl(DeliverMapper deliverMapper, OrderMapper orderMapper, UserMapper userMapper, AddressMapper addressMapper, ProductMapper productMapper) {
        this.deliverMapper = deliverMapper;
        this.orderMapper = orderMapper;
        this.userMapper = userMapper;
        this.addressMapper = addressMapper;
        this.productMapper = productMapper;
    }

    @Override
    public List<Deliver> getAllDelivers() {
        logger.info("Getting all delivers");
        return deliverMapper.findAll();
    }

    @Override
    public Deliver getDeliverById(Integer id) {
        logger.info("Getting deliver by id: {}", id);
        Deliver deliver = deliverMapper.findById(id);
        if (deliver == null) {
            throw new ResourceNotFoundException("Deliver", "id", id);
        }
        return deliver;
    }

    @Transactional
    @Override
    public Deliver createDeliver(CreateDeliverRequest request) {
        logger.info("Creating a new deliver for order id: {}", request.getOrderId());
        Deliver deliver = new Deliver();
        deliver.setAddressId(request.getAddressId());
        deliver.setCurrentAddress(request.getCurrentAddress());
        deliver.setDelivererPhone(request.getDelivererPhone());
        deliver.setOrderId(request.getOrderId());
        deliverMapper.save(deliver);
        logger.info("Successfully created deliver with id: {}", deliver.getId());
        return deliver;
    }

    @Transactional
    @Override
    public Deliver updateDeliver(Integer id, UpdateDeliverRequest request) {
        logger.info("Updating deliver with id: {}", id);
        Deliver deliver = getDeliverById(id);
        deliver.setAddressId(request.getAddressId());
        deliver.setCurrentAddress(request.getCurrentAddress());
        deliver.setDelivererPhone(request.getDelivererPhone());
        deliver.setOrderId(request.getOrderId());
        deliverMapper.update(deliver);
        logger.info("Successfully updated deliver with id: {}", id);
        return deliver;
    }

    @Transactional
    @Override
    public void deleteDeliver(Integer id) {
        logger.info("Deleting deliver with id: {}", id);
        getDeliverById(id); // to check if it exists
        deliverMapper.deleteById(id);
        logger.info("Successfully deleted deliver with id: {}", id);
    }

    @Override
    public DeliverInfoResponse getDeliverInfoById(Integer id) {
        logger.info("Getting deliver info by id: {}", id);
        Deliver deliver = getDeliverById(id);

        Order order = orderMapper.findById(deliver.getOrderId());
        if (order == null) {
            throw new ResourceNotFoundException("Order", "id", deliver.getOrderId());
        }

        User user = userMapper.findById(order.getCustomerId().intValue());
        if (user == null) {
            throw new ResourceNotFoundException("User", "id", order.getCustomerId());
        }

        Address address = addressMapper.findById(order.getAddressId());
        if (address == null) {
            throw new ResourceNotFoundException("Address", "id", order.getAddressId());
        }

        Product product = productMapper.findById(order.getProductId());
        if (product == null) {
            throw new ResourceNotFoundException("Product", "id", order.getProductId());
        }

        DeliverInfoResponse response = new DeliverInfoResponse();
        response.setDeliver(deliver);
        response.setOrder(order);
        response.setUser(user);
        response.setAddress(address);
        response.setProduct(product);

        return response;
    }
} 